<?php

namespace app\service;

use think\facade\Log;

/**
 * PayPal支付服务类.
 */
class PayPalService
{
    private $clientId;
    private $clientSecret;
    private $apiUrl;
    private $accessToken;

    public function __construct()
    {
        // PayPal配置 - 直接从环境变量读取（ThinkPHP可能配置文件加载有问题）
        $this->clientId = config('app.paypal.client_id');
        $this->clientSecret = config('app.paypal.client_secret');
        $isSandbox = config('app.paypal.sandbox');

        // 沙盒环境和生产环境URL
        $this->apiUrl = $isSandbox
            ? 'https://api-m.sandbox.paypal.com'
            : 'https://api-m.paypal.com';

        // 记录配置信息用于调试
        Log::info('PayPal配置初始化'. json_encode([
                'client_id' => substr($this->clientId, 0, 10).'...',
                'client_id_full' => $this->clientId,
                'has_secret' => !empty($this->clientSecret) && $this->clientSecret !== 'YOUR_PAYPAL_CLIENT_SECRET',
                'client_secret_full' => $this->clientSecret,
                'sandbox' => $isSandbox,
                'api_url' => $this->apiUrl,
            ]));
    }

    /**
     * 获取访问令牌.
     */
    private function getAccessToken()
    {
        if ($this->accessToken) {
            return $this->accessToken;
        }

        // 验证配置是否正确
        if ($this->clientId === 'YOUR_PAYPAL_CLIENT_ID' || $this->clientSecret === 'YOUR_PAYPAL_CLIENT_SECRET') {
            Log::error('PayPal配置未正确设置', [
                'client_id' => $this->clientId,
                'client_secret_set' => $this->clientSecret !== 'YOUR_PAYPAL_CLIENT_SECRET',
            ]);
            throw new \Exception('PayPal配置未正确设置，请检查环境变量');
        }

        $url = $this->apiUrl.'/v1/oauth2/token';
        $headers = [
            'Accept: application/json',
            'Accept-Language: en_US',
            'Authorization: Basic '.base64_encode($this->clientId.':'.$this->clientSecret),
        ];

        $data = 'grant_type=client_credentials';

        Log::info('PayPal获取访问令牌请求', [
            'url' => $url,
            'client_id' => substr($this->clientId, 0, 10).'...',
        ]);

        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);

        $response = curl_exec($ch);
        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        $curlError = curl_error($ch);
        curl_close($ch);

        Log::info('PayPal访问令牌响应', [
            'http_code' => $httpCode,
            'curl_error' => $curlError,
            'response' => $response,
        ]);

        if ($httpCode === 200) {
            $result = json_decode($response, true);
            if (isset($result['access_token'])) {
                $this->accessToken = $result['access_token'];
                Log::info('PayPal访问令牌获取成功');

                return $this->accessToken;
            }
        }

        Log::error('PayPal获取访问令牌失败', [
            'http_code' => $httpCode,
            'response' => $response,
            'curl_error' => $curlError,
        ]);

        throw new \Exception('PayPal获取访问令牌失败: HTTP '.$httpCode.' - '.$response);
    }

    /**
     * 创建PayPal订单.
     */
    public function createOrder($orderSn, $description, $amount)
    {
        $accessToken = $this->getAccessToken();
        $url = $this->apiUrl.'/v2/checkout/orders';

        $headers = [
            'Content-Type: application/json',
            'Authorization: Bearer '.$accessToken,
            'PayPal-Request-Id: '.$orderSn,
        ];

        $orderData = [
            'intent' => 'CAPTURE',
            'purchase_units' => [
                [
                    'reference_id' => $orderSn,
                    'description' => $description,
                    'amount' => [
                        'currency_code' => 'USD',
                        'value' => number_format($amount, 2, '.', ''),
                    ],
                ],
            ],
            'application_context' => [
                'brand_name' => config('app.paypal.brand_name', '天纪云'),
                'landing_page' => 'BILLING',
                'user_action' => 'PAY_NOW',
                'return_url' => config('app.paypal.return_url') ?: (config('app.domain', 'https://docs.spacetimesc.com').'/payment/success'),
                'cancel_url' => config('app.paypal.cancel_url') ?: (config('app.domain', 'https://docs.spacetimesc.com').'/payment/cancel'),
            ],
        ];

        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($orderData));
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);

        $response = curl_exec($ch);
        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        curl_close($ch);

        Log::info('PayPal创建订单请求', [
            'order_sn' => $orderSn,
            'amount' => $amount,
            'http_code' => $httpCode,
            'response' => $response,
            'request_data' => $orderData,
        ]);

        if ($httpCode === 201) {
            return json_decode($response, true);
        }

        // 详细记录失败信息
        $responseData = json_decode($response, true);
        Log::error('PayPal创建订单失败', [
            'order_sn' => $orderSn,
            'http_code' => $httpCode,
            'response' => $response,
            'error_details' => $responseData,
            'request_data' => $orderData,
        ]);

        return false;
    }

    /**
     * 获取订单详情.
     */
    public function getOrderDetails($paypalOrderId)
    {
        $accessToken = $this->getAccessToken();
        $url = $this->apiUrl.'/v2/checkout/orders/'.$paypalOrderId;

        $headers = [
            'Content-Type: application/json',
            'Authorization: Bearer '.$accessToken,
        ];

        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);

        $response = curl_exec($ch);
        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        curl_close($ch);

        Log::info('PayPal获取订单详情', [
            'paypal_order_id' => $paypalOrderId,
            'http_code' => $httpCode,
            'response' => $response,
        ]);

        if ($httpCode === 200) {
            return json_decode($response, true);
        }

        Log::error('PayPal获取订单详情失败', [
            'paypal_order_id' => $paypalOrderId,
            'http_code' => $httpCode,
            'response' => $response,
        ]);

        return false;
    }

    /**
     * 捕获订单支付.
     */
    public function captureOrder($paypalOrderId)
    {
        $accessToken = $this->getAccessToken();
        $url = $this->apiUrl.'/v2/checkout/orders/'.$paypalOrderId.'/capture';

        $headers = [
            'Content-Type: application/json',
            'Authorization: Bearer '.$accessToken,
        ];

        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, '{}');
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);

        $response = curl_exec($ch);
        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        curl_close($ch);

        Log::info('PayPal捕获订单支付', [
            'paypal_order_id' => $paypalOrderId,
            'http_code' => $httpCode,
            'response' => $response,
        ]);

        if ($httpCode === 201) {
            return json_decode($response, true);
        }

        Log::error('PayPal捕获订单支付失败', [
            'paypal_order_id' => $paypalOrderId,
            'http_code' => $httpCode,
            'response' => $response,
        ]);

        return false;
    }
}
